/*
 * @author Chris
 * @since 2023/1/26 20:43
 *
 * @brief    The project will ...
 *
 * @note     ...
 *
 * @warning  Do not to ...
 *
 * Change Logs:
 *   Date           Author       Notes
 *   2023/1/26     Chris        the first version
 */

#include "reg51.h"

#define LCD1602_DB P0
#define LCD1602_RS P1_0
#define LCD1602_RW P1_1
#define LCD1602_E P1_5

void ConfigUART(unsigned long baud);

void InitLcd1602();

void LcdShowStr(unsigned char x, unsigned char y, unsigned char c);

int main() {

    // 配置串口
    ConfigUART(9600);
    // 初始化 1602
    InitLcd1602();
    LcdShowStr(2, 1, 'a');

    while (1);
}

void ConfigUART(unsigned long baud) {
    SCON |= 0x50;
    TMOD |= 0x20;
    TH1 = 256 - (11059200 / 12 / 2 / 16) / baud;
    TL1 = TH1;

    EA = 1;
    ET1 = 0;
    ES = 1;
    TR1 = 1;
}

void LcdWaitReady() {
    unsigned char stat;
    LCD1602_DB = 0xFF;
    LCD1602_RS = 0;
    LCD1602_RW = 1;
    do {
        LCD1602_E = 1;
        stat = LCD1602_DB;
        LCD1602_E = 0;
    } while (stat & 0x80);
}

void LcdWriteCmd(unsigned char cmd) {
    LcdWaitReady();
    LCD1602_RS = 0;
    LCD1602_RW = 0;
    LCD1602_DB = cmd;
    LCD1602_E = 1;
    LCD1602_E = 0;
}

void InitLcd1602() {
    LcdWriteCmd(0x38);
    LcdWriteCmd(0x0C);
    LcdWriteCmd(0x06);
    LcdWriteCmd(0x01);
}

void LcdSetCursor(unsigned char x, unsigned char y) {
    if (y == 0) {
        LcdWriteCmd(0x80 | (0x00 + x));
    } else if (y == 1) {
        LcdWriteCmd(0x80 | (0x40 + x));
    } else {}
}

void LcdWriteData(unsigned char c) {
    LcdWaitReady();
    LCD1602_RS = 1;
    LCD1602_RW = 0;
    LCD1602_DB = c;
    LCD1602_E = 1;
    LCD1602_E = 0;
}

void LcdShowStr(unsigned char x, unsigned char y, unsigned char c) {
    LcdSetCursor(x, y);
    LcdWriteData(c);
}

/**
 * 串口中断服务函数
 */
void InterruptUART() __interrupt(4) {
    if (RI) {
        RI = 0;
        LcdShowStr(10, 0, SBUF);
        SBUF += 1;
    }
}